var colors = require('colors');
const { exec } = require('child_process');
ecc = require('eosjs-ecc');
var Base = require('./base');
String.prototype.format = require('./base').strFormat;
var redis = Base.openRedis('redis读取');

var node_url = process.argv[2];

var publish_account = 'wangkes12345';

function unlock() {
    exec('cat wallet-name | xargs -i docker exec eos cleos wallet unlock --name dice --password {}', (err, stdout, stderr) => {
    });
}

var whiteList = {};
whiteList.raogpgneumef = -3;
whiteList.nolagoegnodj = -3;
whiteList.kauiovewrbnv = -3;

whiteList.mortmortmort = +5;
whiteList.jackthethird = +5;


Base.initList[0] = function (done) {
    console.log('启动中[0]...');
    console.log('检测EOS区块链连接...');
    Base.checkDockerEOS(node_url, (isCleos, isDocker) => {
        console.log('checkDockerEOS');
        if (isCleos || isDocker) {
            cleosExe = Base.cleosExe;
            done();
            return;
        }
        else {
            done(true, 'can not find cleos');
            return;
        }
    });
}

function getBettor1() {
    redis.spop('gifts-getlist1', (err, res) => {
        if (err) {
            console.log(err);
            setTimeout(getBettor1, 1000);
            return;
        }
        try {
            if (!res) {
                setTimeout(getBettor1, 1000);
                return;
            }
            var line = JSON.parse(res);

            publish(line);
        } catch (e) {
            console.log(e);
        }
        setTimeout(getBettor1, 1000);
    });
}
function getBettor2() {
    redis.spop('gifts-getlist2', (err, res) => {
        if (err) {
            console.log(err);
            setTimeout(getBettor2, 1000);
            return;
        }
        try {
            if (!res) {
                setTimeout(getBettor2, 1000);
                return;
            }
            var line = JSON.parse(res);

            publish(line);
        } catch (e) {
            console.log(e);
        }
        setTimeout(getBettor2, 1000);
    });
}
function getBettor3() {
    redis.spop('gifts-getlist3', (err, res) => {
        if (err) {
            console.log(err);
            setTimeout(getBettor3, 1000);
            return;
        }
        try {
            if (!res) {
                setTimeout(getBettor3, 1000);
                return;
            }
            var line = JSON.parse(res);

            publish(line);
        } catch (e) {
            console.log(e);
        }
        setTimeout(getBettor3, 1000);
    });
}
function getBettor4() {
    redis.spop('gifts-getlist4', (err, res) => {
        if (err) {
            console.log(err);
            setTimeout(getBettor4, 1000);
            return;
        }
        try {
            if (!res) {
                setTimeout(getBettor4, 1000);
                return;
            }
            var line = JSON.parse(res);

            publish(line);
        } catch (e) {
            console.log(e);
        }
        setTimeout(getBettor4, 1000);
    });
}

Base.initList[1] = function (done) {
    getBettor1();
    /*getBettor2();
    getBettor3();
    getBettor4();*/
    done();
}

const Hexstring2btye = (str) => {
    let pos = 0;
    let len = str.length;
    if (len % 2 !== 0) {
        return null;
    }
    len /= 2;
    let hexA = new Uint8Array(len);
    for (let i = 0; i < len; i++) {
        let s = str.substr(pos, 2);
        let v = parseInt(s, 16);
        hexA[i] = v;
        pos += 2;
    }
    return hexA;
};

function make_random(roll_under, skipFlag) {
    var skipList = [];
    var minNumber = 1;
    var maxNumber = 101;
    var count = 1000;
    // 左边减去随机值
    if (skipFlag > 0) {
        while (skipList.length < Math.abs(skipFlag) && count--) {
            if (Base.randomInt(2) === 0) {
                var newSkip = Base.randomRangeInt(minNumber, roll_under);
                if (skipList.indexOf(newSkip) === -1) {
                    skipList.push(newSkip);
                    if (skipList.length === Math.abs(skipFlag)) {
                        break;
                    }
                }
            }
        }
    }

    // 右边减去随机值
    if (skipFlag < 0) {
        while (skipList.length < Math.abs(skipFlag) && count--) {
            if (Base.randomInt(2) === 0) {
                var newSkip = Base.randomRangeInt(roll_under, maxNumber);
                if (skipList.indexOf(newSkip) === -1) {
                    skipList.push(newSkip);
                    if (skipList.length === Math.abs(skipFlag)) {
                        break;
                    }
                }
            }
        }
        //whiteList.nolagoegnodj = [100, 99];
    }
    return skipList;
}

var MULTIPLE = 100;
//var MULTIPLE = 10000;
function getAmountFromRoomID(roomid) {
    switch (roomid) {
        case 1: return 1 * MULTIPLE; break;
        case 2: return 10 * MULTIPLE; break;
        case 3: return 100 * MULTIPLE; break;
        case 4: return 1000 * MULTIPLE; break;
    }
}

function checkinputs(bets) {
    return true
}

function formatPlayerBets(bets) {
    //console.log(JSON.stringify(bets))
    console.log('=====================================================')
    var all_payout = 0;
    for (var i = 0; i < bets.length; i++) {
        console.log('player : ' + bets[i].account + ' roll: ' + bets[i].roll + ' payout: ' + bets[i].payout);
        all_payout += bets[i].payout;
    }
    return all_payout;
}

function publish(line) {
    console.log(line);

    if (!checkinputs(line.betinfoList)) {
        return;
    }

    var player_bets = [];
    var sum_of_rolls = 0;

    for (var i = 0; i < line.betinfoList.length; i++) {
        param_sig = ecc.sign(line.betinfoList[i].seed_hash + Base.randomRangeInt(1, 10000), '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3');
        buff_sig = ecc.Signature.fromString(param_sig).toBuffer();

        let sigBuff = new Uint8Array(buff_sig.length + 1);
        for (var len = 0; len < buff_sig.length; len++) {
            sigBuff[len + 1] = buff_sig[len];
        }
        shaByte = Hexstring2btye(ecc.sha256(sigBuff));

        var number = 0;
        number += parseInt(shaByte[0]);
        number += parseInt(shaByte[1]);
        number += parseInt(shaByte[2]);
        number += parseInt(shaByte[3]);
        number += parseInt(shaByte[4]);
        number += parseInt(shaByte[5]);
        number += parseInt(shaByte[6]);
        number += parseInt(shaByte[7]);
        number %= 100;
        number += 1;
        //console.log('betinfoList ' + i + ' with signHash: ' + param_sig + ' with random number = ' + number)

        sum_of_rolls += number;

        player_bets.push({
            account: line.betinfoList[i].player,
            roll: number,
            amount: line.betinfoList[i].quantity,
        })
    }

    var amount = getAmountFromRoomID(line.roomid);
    var max_payout = 0;
    var max_payout_index = 0;
    var house_payout_index = Base.randomRangeInt(0, 10);
    var house_payout = 0;

    for (var i = 0; i < player_bets.length; i++) {
        thePayout = Math.floor(amount * player_bets[i].roll * 1.0 / sum_of_rolls);

        if (i === house_payout_index) {
            house_payout = thePayout;
            player_bets[i].payout = 0;
            continue;
        }

        player_bets[i].payout = thePayout;
        if (player_bets[i].payout > max_payout) {
            max_payout = player_bets[i].payout;
            max_payout_index = i;
        }
    }

    for (var i = 0; i < player_bets.length; i++) {
        if (i === max_payout_index) {

        }
        else {
            player_bets[i].payout += amount;
        }
    }

    //console.log('payout info: ' + JSON.stringify(player_bets))
    var all_payout = formatPlayerBets(player_bets);
    house_payout = (amount * player_bets.length) - all_payout;

    console.log(
        ' all pay out: ' + all_payout +
        ' max payout: ' + max_payout +
        ' max payout index: ' + max_payout_index +
        ' house payout index: ' + house_payout_index +
        ' house payout :' + house_payout
    );

    //var onchainStr = player_bets[max_payout_index].account + ':' + max_payout + ',';
    var notice = {
        "amount":amount,
        "roomid":line.roomid,
        "date":new Date(),
        "issue":line.issue
    }
    var content =[];
    var onchainStr = '';
    for (var i = 0; i < player_bets.length; i++) {

        if (i === house_payout_index) {
            onchainStr += player_bets[house_payout_index].account + ':' + player_bets[house_payout_index].payout + ',';
            content.push({
                "user":player_bets[i].account,
                "payamount":player_bets[i].payout
            });
            continue;
        }

        if (i === max_payout_index) {
            onchainStr += player_bets[max_payout_index].account + ':' + max_payout + ',';
            content.push({
                "user":player_bets[i].account,
                "payamount":max_payout
            });
            continue;
        }

        if (player_bets.length - 1 === i) {
            onchainStr += player_bets[i].account + ':' + player_bets[i].payout + ',';
            content.push({
                "user":player_bets[i].account,
                "payamount":player_bets[i].payout
            });
        }
        else {
            onchainStr += player_bets[i].account + ':' + player_bets[i].payout + ',';
            content.push({
                "user":player_bets[i].account,
                "payamount":player_bets[i].payout
            });
        }
    }
    onchainStr = onchainStr.substr(0,onchainStr.length-1)
    //onchainStr += player_bets[house_payout_index].account + ':' + player_bets[house_payout_index].payout;
    notice.content = content;


    console.log(onchainStr);

    var cmd = cleosExe + ' --url ' + node_url + ' push action fastwingifts resolvebet \'[' + line.roomid + ',' + line.issue + ',' + '"' + onchainStr + '"' + ']\' -p ' + publish_account;
    console.log(cmd);
    exec(cmd, (err, stdout, stderr) => {
        var temp = JSON.parse(JSON.stringify(player_bets));
        if (err) { console.log(err); return; }
        redis.sadd('notice-all-activebets', JSON.stringify(notice), (err1, res1) => {
            console.log(err1,res1);
        });
        var mapObj = new Map();
        for (var i = 0; i < temp.length; i++) {
            if (mapObj.get(temp[i].account)) {
                mapObj.set(temp[i].account, parseInt(mapObj.get(temp[i].account)) + parseInt(temp[i].payout));
            } else {
                mapObj.set(temp[i].account, temp[i].payout)
            }
        }

        mapObj.forEach(function (val, key, mapObj) {
            func(key,val);
        });

    });
}
function func(key, val)
{
    redis.hget("total-gifts",key,function(err,res)
    {
        if (res)
        {
            redis.hset("total-gifts",key,parseInt(val)+parseInt(res));
        }
        else
        {
            redis.hset("total-gifts",key,val);
        }
    })
};



Base.begin();
//Base.requireNetServer();

